import json
import multiprocessing
import socket
import threading
import traceback
from asyncio.log import logger
import concurrent.futures
import pyodbc
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFontMetrics
from PyQt5.QtWidgets import QMainWindow, QDialog, QMessageBox, QFileDialog
from multiprocessing.pool import ThreadPool
from test_api import getdir
from view import SystemSettings


class ConnectionThread(threading.Thread):
    def __init__(self, connection_string):
        super().__init__()
        self.connection_string = connection_string
        self.connection = None
        self.error = None

    def run(self):
        try:
            self.connection = pyodbc.connect(self.connection_string)
        except pyodbc.Error as e:
            self.error = e


class SystemSet(SystemSettings.Ui_Dialog, QDialog):
    def __init__(self):
        super(SystemSet, self).__init__()
        self.setupUi(self)
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.pushButton.clicked.connect(self.close_button)  # 连接关闭窗口按钮
        self.pushButton_3.clicked.connect(self.close_button)  # 连接关闭窗口按钮
        self.pushButton_2.clicked.connect(self.confirm)   # 连接确定按钮
        self.pushButton_8.clicked.connect(self.confirm_connection)   # 连接数据库连接测试按钮
        # 连接标签点击事件到选择文件的方法
        self.label_4.mousePressEvent = self.select_file

        self.update_message()


    def select_file(self, event):
        try:
            # 打开文件夹选择对话框
            self.directory = QFileDialog.getExistingDirectory(self, "选择文件夹", "")
            # 将选定的文件夹路径显示在 label_2 中
            if self.directory:
                self.setLabelTextWithElide(self.label_2, self.directory)
        except Exception as e:
            QMessageBox.critical(self, "错误", f"选择文件夹时发生错误: {e}")

    def setLabelTextWithElide(self, label, text):
        try:
            fm = QFontMetrics(label.font())  # 获取字体度量
            width = label.width() - 10  # 计算标签的实际可用宽度，减去一些边距

            # 计算文本所需的宽度
            textWidth = fm.width(text)

            # 根据文本宽度与标签宽度比较决定是否省略
            if textWidth > width:
                elided_text = fm.elidedText(text, Qt.ElideMiddle, width)  # 如果文本过长，则使用省略形式
            else:
                elided_text = text  # 如果文本没有超过标签宽度，不需要省略

            label.setText(elided_text)  # 设置标签文本
            label.setToolTip(text)  # 设置完整文本为工具提示
        except Exception as e:
            logger.error(f"设置标签文本时发生错误: {e}")
            logger.error(traceback.format_exc())

    def update_message(self):
        # 读取设置文件
        self.settings_file = getdir() + 'api/ConfigJson.txt'
        with open(self.settings_file, 'r', encoding='utf-8') as file:
            settings = json.load(file)
        self.lineEdit.setText(settings["dataIp"])
        self.lineEdit_4.setText(settings["database"])
        self.lineEdit_2.setText(settings["user"])
        self.lineEdit_3.setText(settings["password"])
        self.label_2.setText(settings["filepath"])

    def confirm(self):
        # 读取设置文件
        self.settings_file = getdir() + 'api/ConfigJson.txt'
        with open(self.settings_file, 'r', encoding='utf-8') as file:
            settings = json.load(file)
        self.year = self.comboBox.currentText()
        self.filepath = self.label_2.text()
        self.dataIp = self.lineEdit.text()
        self.database = self.lineEdit_4.text()
        self.user = self.lineEdit_2.text()
        self.password = self.lineEdit_3.text()

        # 更新的标志位
        updated = False
        if settings["year"] != self.year:
            settings["year"] = self.year
            updated = True

        if settings["filepath"] != self.filepath:
            settings["filepath"] = self.filepath
            updated = True

        if settings["dataIp"] != self.dataIp:
            settings["dataIp"] = self.dataIp
            updated = True

        if settings["database"] != self.database:
            settings["database"] = self.database
            updated = True

        if settings["user"] != self.user:
            settings["user"] = self.user
            updated = True

        if settings["password"] != self.password:
            settings["password"] = self.password
            updated = True

        if updated:
            # 将修改后的内容写回文件
            with open(self.settings_file, 'w', encoding='utf-8') as file:
                json.dump(settings, file, ensure_ascii=False, indent=4)
            # 弹出提示框显示更新的信息
            QMessageBox.information(self, "确认", f"已更新文件路径为: {self.filepath}")
            self.close()
        else:
            # 弹出提示框
            QMessageBox.information(self, "提示", "文件路径未更改，当前路径已是相同。")

    # def confirm_connection(self):
    #     try:
    #         # 构建连接字符串
    #         connection_string = (
    #             r'DRIVER={{ODBC Driver 17 for SQL Server}};'
    #             r'SERVER={dataIp};'  # 使用 settings['dataIp']
    #             r'DATABASE={database};'
    #             r'UID={user};'
    #             r'PWD={password};'
    #             r'Connect Timeout=2'  # 设置连接超时时间为2秒
    #         ).format(dataIp=self.lineEdit.text(),
    #                  database=self.lineEdit_4.text(),
    #                  user=self.lineEdit_2.text(),
    #                  password=self.lineEdit_3.text())
    #         # 连接数据库
    #         connection = pyodbc.connect(connection_string)
    #         # 连接成功，关闭连接
    #         connection.close()
    #         # 弹出成功提示框
    #         QMessageBox.information(None, "数据库连接成功", "成功连接到数据库。")
    #     except pyodbc.Error as e:
    #         # 连接失败，弹出失败提示框
    #         QMessageBox.critical(None, "数据库连接失败", str(e))

    # def confirm_connection(self):
    #     try:
    #         # 构建连接字符串
    #         connection_string = (
    #             r'DRIVER={{ODBC Driver 17 for SQL Server}};'
    #             r'SERVER={dataIp};'
    #             r'DATABASE={database};'
    #             r'UID={user};'
    #             r'PWD={password}'
    #         ).format(dataIp=self.lineEdit.text(),
    #                  database=self.lineEdit_4.text(),
    #                  user=self.lineEdit_2.text(),
    #                  password=self.lineEdit_3.text())
    #
    #         # 使用 ThreadPoolExecutor 来实现超时控制
    #         with concurrent.futures.ThreadPoolExecutor() as executor:
    #             future = executor.submit(pyodbc.connect, connection_string)
    #             try:
    #                 # 设置超时时间为2秒
    #                 connection = future.result(timeout=2)
    #                 # 连接成功，关闭连接
    #                 connection.close()
    #                 # 弹出成功提示框
    #                 QMessageBox.information(self, "数据库连接成功", "成功连接到数据库。")
    #             except concurrent.futures.TimeoutError:
    #                 # 超时处理
    #                 QMessageBox.critical(self, "数据库连接失败", "连接超时，请检查网络或数据库配置。")
    #             except pyodbc.Error as e:
    #                 # 连接失败处理
    #                 QMessageBox.critical(self, "数据库连接失败", str(e))
    #     except Exception as e:
    #         QMessageBox.critical(self, "数据库连接失败", str(e))

    def connect_to_database(self, connection_string):
        try:
            connection = pyodbc.connect(connection_string)
            return True, connection
        except pyodbc.Error as e:
            return False, str(e)

    def confirm_connection(self):
        try:
            connection_string = (
                r'DRIVER={{ODBC Driver 17 for SQL Server}};'
                r'SERVER={dataIp};'
                r'DATABASE={database};'
                r'UID={user};'
                r'PWD={password}'
            ).format(dataIp=self.lineEdit.text(),
                     database=self.lineEdit_4.text(),
                     user=self.lineEdit_2.text(),
                     password=self.lineEdit_3.text())

            with ThreadPool(processes=1) as pool:
                result = pool.apply_async(self.connect_to_database, args=(connection_string,))
                success, result = result.get(timeout=2)

            if success:
                result.close()
                QMessageBox.information(self, "数据库连接成功", "成功连接到数据库。")
            else:
                QMessageBox.critical(self, "数据库连接失败", result)
        except multiprocessing.TimeoutError:
            QMessageBox.critical(self, "数据库连接失败", "连接超时，请检查网络或数据库配置。")
        except Exception as e:
            QMessageBox.critical(self, "数据库连接失败", str(e))

    def close_button(self):
        self.close()